#pragma once

#include <cstdint>
#include <string>
#include <unordered_map>
#include <memory>
#include <mutex>

using namespace std;

uint64_t guser_id = 1; // 全局的用户ID,每注册一个新用户一次就++
mutex guser_id_mutex;  // 保护guser_id，防止出现线程安全问题

class User
{
public:
    User(uint64_t id,const string &name,const string& password)
        : _username(name),
          _islogin(false),
          _user_id(id),
          _password(password)
    {
    }
    void SetisLogin(bool stu)
    {
        _islogin = stu;
    }
    bool isLogin()const
    {
        return _islogin;
    }
    uint64_t Id()const
    {
        return _user_id;
    }
    string Name()const
    {
        return _username;
    }
    bool isPasswordCorrect(const string &password)const//判断密码是否正确
    {
        return _password==password;
    }
private:
    string _username;
    bool _islogin; // 是否处于登录状态
    uint64_t _user_id;
    string _password;
};

class UserTable
{
public:
    UserTable()
    {
    }
    bool isExistence_Id(const uint64_t id)//使用ID判断用户是否存在
    {
        lock_guard<mutex> lock(_m);

        if (_table.find(id) == _table.end()) // 用户不存在
        {
            return false;
        }
        return true;
    }

    bool isExistence_Name(const string &name)//使用用户名判断用户是否存在
    {
        lock_guard<mutex> lock(_m);

        if (_nametoid.find(name) == _nametoid.end())
        {
            return false;
        }
        return true;
    }
    bool AddUser(const uint64_t id, const User &s)
    {
        lock_guard<mutex> lock(_m);

        if (_table.find(id) != _table.end()) // 不存在才能插入
        {
            return false;
        }

        _table.insert({id, make_shared<User>(s)});
        
        _nametoid.insert({s.Name(),id});
        _idtoname.insert({id,s.Name()});

        return true;
    }
    bool DleteUser(const uint64_t id)
    {
        lock_guard<mutex> lock(_m);

        if (_table.find(id) == _table.end()) // 存在才能删除
        {
            return false;
        }
        _table.erase(id);

        _nametoid.erase(_idtoname[id]);
        _idtoname.erase(id);
        return true;
    }

    bool SetisLogin(const uint64_t id,const bool stu) //修改用户登录状态
    {
        lock_guard<mutex> lock(_m);

        if (_table.find(id) == _table.end())
        {
            return false;
        }

        _table[id]->SetisLogin(stu);

        return true;
    }

    bool isLogin(const uint64_t id) // 判断指定用户是否登录
    {
        lock_guard<mutex> lock(_m);

        if (_table.find(id) == _table.end()) // 不存在也视为没有登录
        {
            return false;
        }

        return _table[id]->isLogin();
    }
    uint64_t NameToId(const string& name)
    {
        lock_guard<mutex> lock(_m);

        return _nametoid[name];
    }
    bool isPasswordCorrect(const uint64_t id,const string &password)//判断密码是否正确
    {
        lock_guard<mutex> lock(_m);

        if (_table.find(id) == _table.end()) 
        {
            return false;
        }

        return _table[id]->isPasswordCorrect(password);
    }

private:
    unordered_map<uint64_t, shared_ptr<User>> _table; 
    unordered_map<string, uint64_t> _nametoid;    
    unordered_map<uint64_t,string> _idtoname;     
    mutex _m;      
};

UserTable guser_table;

